﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using MapLibrary;

namespace MapLibrary
{
    public class Map
    {
        private List<Layer> mLayers;
        private List<string> mLayerAssets;

        private string mLayerAssetsAsset;

        private string mMapName;

        private Palette mPalette;

        public Map()
        {
            mLayers = new List<Layer>();
            mLayerAssets = new List<string>();

            mPalette = new Palette();
            //mMapName = "testing";

            //ConstructLayers();
        }

        /**
         * Map is composed of 10 layers
         */
        public void ConstructLayers()
        {
            if (mLayers.Count < 10)
            {
                for (int i = 0; i < 10; i++)
                {
                    mLayers.Add(new Layer());
                }
            }
        }

        public string Name
        {
            get { return mMapName; }
            set { mMapName = value; }
        }

        public Palette Palette
        {
            get { return mPalette; }
            set { mPalette = value; }
        }

        public List<Layer> Layers
        {
            get { return mLayers; }
            set { mLayers = value; }
        }

        public void Draw(SpriteBatch batch, WorldViewport Viewport)
        {
            foreach (Layer layer in mLayers)
            {
                layer.Draw(batch, Viewport);
            }
        }

        public string LayerAssetListAsset
        {
            get { return mLayerAssetsAsset; }
            set { mLayerAssetsAsset = value; }
        }

        public void AddLayerAsset(string layerAsset)
        {
            mLayerAssets.Add(layerAsset);
        }

        //[ContentSerializerIgnore]
        public List<string> LayerAssets
        {
            get { return mLayerAssets; }
        }

        public void LoadAllLayers(ContentManager content)
        {
            mLayerAssets = content.Load<List<string>>(mLayerAssetsAsset);

            foreach (string asset in mLayerAssets)
            {
                mLayers.Add(content.Load<Layer>(asset));
            }
        }

        public void Load(ContentManager pContent)
        {
            //testing
            ConstructLayers();
            this.Name = "testing_map_save";
            MapNode Node = new MapNode();
            Node.Position = new Microsoft.Xna.Framework.Vector2(100, 100);
            Node.Rotation = 100;
            Node.Scale = new Microsoft.Xna.Framework.Vector2(1.0f, 1.0f);
            Node.TextureAsset = @"Crate-icon";
            Node.Load(pContent);
            this.Palette.AddAsset(Node.TextureAsset);

            mLayers[0].AddNode(Node);
        }
    }

    public class MapContentReader : ContentTypeReader<Map>
    {
        protected override Map Read(ContentReader input, Map existingInstance)
        {
            Map map;
            if (existingInstance != null)
                map = existingInstance;
            else
                map = new Map();

            map.Name = input.ReadString();
            map.Palette = input.ReadObject<Palette>();
            int numLayers = input.ReadInt32();
            for (int i = 0; i < numLayers; i++)
            {
                map.Layers.Add(input.ReadObject<Layer>());
            }
            
            return map;
        }
    }

    //[ContentTypeWriter]
    public class MapTypeWriter : ContentTypeWriter<Map>
    {
        protected override void Write(ContentWriter output, Map value)
        {
            output.Write(value.Name);
            output.WriteObject<Palette>(value.Palette);
            output.Write(value.Layers.Count);

            foreach (Layer lay in value.Layers)
            {
                output.WriteObject<Layer>(lay);
            }
        }

        public override string GetRuntimeReader(TargetPlatform targetPlatform)
        {
            // TODO: change this to the name of your ContentTypeReader
            // class which will be used to load this data.
            return typeof(MapContentReader).AssemblyQualifiedName;
        }
    }
}
